namespace Resharper.Abstractions.CodeDom.Statements.ForStatements
{
  using System.Collections.Generic;
  using System.Linq;
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.CSharp.Tree;
  using Resharper.Abstractions.CodeDom.Expressions;
  using Resharper.Abstractions.CodeDom.Statements.LocalVariables;

  /// <summary>Defines the <see cref="ForStatement"/> class.</summary>
  public class ForStatement : Statement
  {
    #region Constructors and Destructors

    /// <summary>Initializes a new instance of the <see cref="ForStatement"/> class.</summary>
    /// <param name="statement">The expression.</param>
    internal ForStatement([NotNull] IForStatement statement) : base(statement)
    {
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets the expression.
    /// </summary>
    [CanBeNull]
    public Expression Condition
    {
      get
      {
        var condition = this.InternalForStatement.Condition;

        return condition != null ? ExpressionFactory.GetExpression(condition) : null;
      }
    }

    /// <summary>
    /// Gets the initialized variables.
    /// </summary>
    [NotNull]
    public IEnumerable<LocalVariable> InitializedVariables
    {
      get
      {
        var declarations = this.InternalForStatement.InitializerDeclarations;
        if (declarations == null)
        {
          yield break;
        }

        foreach (var declaration in declarations)
        {
          var declaredElement = declaration.DeclaredElement;

          if (declaredElement != null)
          {
            yield return new LocalVariable(declaredElement);
          }
        }
      }
    }

    /// <summary>
    /// Gets the iterator expressions.
    /// </summary>
    [NotNull]
    public IEnumerable<Expression> IteratorExpressions
    {
      get
      {
        var expressions = this.InternalForStatement.IteratorExpressions;

        return expressions != null ? expressions.Select(ExpressionFactory.GetExpression) : Enumerable.Empty<Expression>();
      }
    }

    /// <summary>
    /// Gets the internal for statement.
    /// </summary>
    [NotNull]
    internal IForStatement InternalForStatement
    {
      get
      {
        return (IForStatement)this.InternalStatement;
      }
    }

    #endregion
  }
}